package cn.tedu.aop.demo;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
public class SystoutAspect {
////    @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.*(..))")
////    @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.add(..))")
////    @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.add(int,int))")
////    @Before("execution(public int cn.tedu.aop.demo.CalculatorImpl.add(int,double))")//错误
////    @Before("execution(public double cn.tedu.aop.demo.CalculatorImpl.add(double,double))")
////    @Before("execution(public java.lang.String cn.tedu.aop.demo.CalculatorImpl.add(java.lang.String,java.lang.String))")
////    @Before("execution(public * cn.tedu.aop.demo.CalculatorImpl.add(..))")
//    @Before("execution(public * cn.tedu.aop.demo.CalculatorImpl.*(..))")
//    public void before(JoinPoint joinPoint){
//        /*
//        System.out.println("切面类在方法调用前被调用了！");
//
//        Object target = joinPoint.getTarget();
//        System.out.println("目标对象："+target);//目标对象：cn.tedu.aop.demo.CalculatorImpl@d1a10ac
//        Class cls = target.getClass();//类名
//        System.out.println(cls);//    class cn.tedu.aop.demo.CalculatorImpl
//        System.out.println(cls.getName());//cn.tedu.aop.demo.CalculatorImpl
//        System.out.println(cls.getSimpleName());//           CalculatorImpl
//
//        Signature signature = joinPoint.getSignature();
//        System.out.println(signature);//int cn.tedu.aop.demo.CalculatorImpl.add(int,int)
//        String methodName = signature.getName();
//        System.out.println("方法名"+methodName);//方法名add
//
//        Object[] args = joinPoint.getArgs();
////        for (Object arg : args) {
////            System.out.println("参数："+arg);
////        }
//        System.out.println("实参："+ Arrays.toString(args));
//        */
//        System.out.println("---------------------------------------------------------");
//        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
//        String name = joinPoint.getSignature().getName();
//        System.out.println(simpleName+"."+name+"():开始执行");
//    }
//
//    @AfterReturning(
//            value = "execution(public * cn.tedu.aop.demo.CalculatorImpl.*(..))",
//            returning = "returnValue"
//    )
//    public void afterReturning(JoinPoint joinPoint,Object returnValue){
//        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
//        String name = joinPoint.getSignature().getName();
//        System.out.println(simpleName+"."+name+"():执行完毕，返回值是:"+returnValue);
//        System.out.println("切面类在方法调用后被调用了！");
//    }
//    @After("execution(public * cn.tedu.aop.demo.CalculatorImpl.*(..))")//最后执行，类似于finally
//    public void after(JoinPoint joinPoint){
//        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
//        String name = joinPoint.getSignature().getName();
//        System.out.println(simpleName+"."+name+"():执行完毕!");
//    }
//    @AfterThrowing(
//            value = "execution(public * cn.tedu.aop.demo.CalculatorImpl.*(..))",
//            throwing = "e"
//    )
//    public void afterThrowing(JoinPoint joinPoint, Exception e){
//        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
//        String name = joinPoint.getSignature().getName();
//        System.out.println(simpleName+"."+name+"():抛出异常了，异常是:"+e.getMessage());
//    }


    @Around("execution(public * cn.tedu.aop.demo.CalculatorImpl.*(..))")
    public Object around(ProceedingJoinPoint point){
        String simpleName = point.getTarget().getClass().getSimpleName();
        String name = point.getSignature().getName();
        Object[] args = point.getArgs();
        try {
            //@Before
            System.out.println(simpleName+"."+name+"():开始执行");
            Object returnValue = point.proceed();
            //@AfterReturning
            System.out.println(simpleName+"."+name+"():执行完毕，返回值是:"+returnValue);
            return returnValue;
        } catch (Throwable e) {
            //@AfterThrowing
            System.out.println(simpleName+"."+name+"():抛出异常了，异常是:"+e.getMessage());
            throw new RuntimeException(e);
        } finally {
            //@After
            System.out.println(simpleName+"."+name+"():执行完毕!");
        }
    }
}
